package com.seecen.utils;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Slf4j
@Component
public class FileUploadUtil {

    @Value("${file.upload.path}")
    private String uploadPath;

    @Value("${vue.url.prefix}")
    private String vueUrlPrefix;

    public String uploadImage(MultipartFile file) throws IOException {
        //1 验证文件后缀名是否正确？
        validateFile(file);
        //2 生成一个新的文件名，保存在服务器上
        String originalFilename = file.getOriginalFilename();
        String newFileName = generateFileName(originalFilename);
        //3 判断一下存到 服务器的目录是否存在？？，如果不存在新建
        //创建一个日期目录
        String datePath = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
        // 确保路径正确拼接，处理斜杠问题
        String normalizedUploadPath = uploadPath.endsWith("/") ? uploadPath : uploadPath + "/";
        String fullPath = normalizedUploadPath + datePath;
        log.info("原始上传路径配置: {}", uploadPath);
        log.info("标准化上传路径: {}", normalizedUploadPath);
        log.info("日期路径: {}", datePath);
        log.info("完整上传路径: {}", fullPath);
        File dir = new File(fullPath);
        if(!dir.exists()) {
            boolean created = dir.mkdirs();
            log.info("创建目录: {}, 结果: {}", fullPath, created);
        }
        //4 文件传参，把file保存到服务器
        File dest = new File(fullPath + "/" + newFileName);
        log.info("保存文件到: {}", dest.getAbsolutePath());
        file.transferTo(dest);
        log.info("文件保存成功，文件大小: {}", dest.length());

        //5返回一个可以浏览器访问该上传文件的地址
        String accessUrl = vueUrlPrefix + datePath + "/" + newFileName;
        log.info("生成访问URL: {}", accessUrl);
        return accessUrl;
    }

    @Value("${spring.servlet.multipart.max-file-size}")
    private String maxFileSize;
    //验证文件
    private void validateFile(MultipartFile file) {
        if(file.isEmpty()) {
            throw new RuntimeException("文件名不能为空");
        }
        //上传大小转化
        if(!ObjectUtil.isNotEmpty(maxFileSize)) {
            throw new RuntimeException("文件大小设置为空");
        }

        //MB单位要换算
        Integer size = Integer.valueOf(maxFileSize.replace("MB",""))
                * 1024 * 1024;
        if(file.getSize() > size) {
            throw new RuntimeException("文件到小不能超过 "+ maxFileSize);
        }

        //验证后缀名为图片
        String originalFilename = file.getOriginalFilename();
        String fileExtension = getFileExtension(originalFilename);

        boolean isUsed = false;
        for (String ext : IMAGE_EXTENSIONS) {
            if(ext.equalsIgnoreCase(fileExtension)) {
                isUsed = true;
                break;
            }
        }
        if(!isUsed) {
            throw new RuntimeException("不支持该文件格式的图片上传！");
        }
    }

    //这个信息需要配置到 application.yml
    private static final String[] IMAGE_EXTENSIONS
            = {".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp"};
    private String getFileExtension(String fileName) {
        if(ObjectUtil.isNull(fileName) ||  !fileName.contains(".")) {
            throw new RuntimeException("上传的文件格式不正确");
        }
        return fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
    }

    private String generateFileName(String fileName) {
        return UUID.randomUUID().toString().replace("-", "") + fileName;
    }
}
